package com.lineengine.lineengine.engine;

import cn.hutool.core.date.SystemClock;
import com.lineengine.lineengine.common.ErrorType;
import com.lineengine.lineengine.common.CommonErrorCode;
import com.lineengine.lineengine.context.IContext;
import com.lineengine.lineengine.node.INode;
import com.lineengine.lineengine.result.DefaultResult;
import com.lineengine.lineengine.result.IResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


/**
 * <p>
 * 引擎默认实现
 * </p>
 *
 * @author wenrong.yu
 * @since 2020-11-07 21:24
 */
public abstract class AbstractEngine<T extends IContext<T>> implements IEngine<T> {
    private static final Logger LOGGER = LoggerFactory.getLogger(AbstractEngine.class);

    @Override
    public IResult<T> process(INode<T> node, T context) {
        try {
            long start = SystemClock.now();
            IResult<T> result = node.execute(context);
            long costTime = SystemClock.now() - start;
            if (costTime > 500) {
                LOGGER.info("IEngine process costTime: {}, nodeCostTime: {}", costTime, context.printCostTime());
            }
            if (!result.isSuccess()) {
                this.reset(context); // 失败回滚
            }
            return result;
        } catch (Exception e) {
            LOGGER.warn("Occurs Exception, start to rollback.", e);
            this.reset(context); // 异常回滚


            return DefaultResult.fail(ErrorType.SERVER, CommonErrorCode.INTERNAL_SERVER_ERROR);
        }
    }
}